package com.iotechn.unimall.app.api.integralactivity;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.github.binarywang.wxpay.service.WxPayService;
import com.iotechn.unimall.app.api.category.CategoryService;
import com.iotechn.unimall.app.api.distribution.DistributionService;
import com.iotechn.unimall.app.api.order.OrderServiceImpl;
import com.iotechn.unimall.app.executor.GlobalExecutor;
import com.iotechn.unimall.biz.service.distribution.DistributionBizService;
import com.iotechn.unimall.biz.service.freight.FreightBizService;
import com.iotechn.unimall.biz.service.goods.GoodsBizService;
import com.iotechn.unimall.biz.service.integral.IntegralBizService;
import com.iotechn.unimall.biz.service.notify.AdminNotifyBizService;
import com.iotechn.unimall.biz.service.order.OrderBizService;
import com.iotechn.unimall.biz.service.user.UserBizService;
import com.iotechn.unimall.core.exception.AppServiceException;
import com.iotechn.unimall.core.exception.ExceptionDefinition;
import com.iotechn.unimall.core.exception.ServiceException;
import com.iotechn.unimall.core.util.*;
import com.iotechn.unimall.data.component.CacheComponent;
import com.iotechn.unimall.data.component.LockComponent;
import com.iotechn.unimall.data.domain.*;
import com.iotechn.unimall.data.dto.goods.SkuDTO;
import com.iotechn.unimall.data.dto.integralactivity.IntegralGoodsRequestDTO;
import com.iotechn.unimall.data.dto.order.OrderDTO;
import com.iotechn.unimall.data.dto.order.OrderRequestDTO;
import com.iotechn.unimall.data.dto.order.OrderRequestSkuDTO;
import com.iotechn.unimall.data.enums.*;
import com.iotechn.unimall.data.mapper.*;
import com.iotechn.unimall.data.util.SessionUtil;
import com.iotechn.unimall.plugin.core.inter.IPluginPaySuccess;
import com.iotechn.unimall.plugin.core.manager.PluginsManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import com.iotechn.unimall.biz.service.orderlog.OrderLogBizService;

@Service
public class IntegralOrderServiceImpl implements IntegralOrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
    private static final String CA_SPU_PREFIX = "CA_SPU_";
    private static final String TAKE_ORDER_LOCK = "TAKE_INTEGRAL_ORDER_";

    @Value("${com.iotechn.unimall.machine-no}")
    private String MACHINE_NO;

    @Value("${com.iotechn.unimall.env}")
    private String ENV;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private OrderSkuMapper orderSkuMapper;
    @Autowired
    private CacheComponent cacheComponent;


    @Autowired
    private RefundOrderMapper refundOrderMapper;
    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private LockComponent lockComponent;

    @Autowired
    private OrderBizService orderBizService;

    @Autowired
    private FreightBizService freightBizService;

    @Autowired
    private UserBizService userBizService;
    @Autowired
    private AdminNotifyBizService adminNotifyBizService;

    @Autowired
    private DistributionBizService distributionBizService;

    @Autowired
    private GroupShopMapper groupShopMapper;

    @Autowired
    private GoodsBizService goodsBizService;

    @Autowired
    private IntegralGoodsMapper integralGoodsMapper;
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private UserCouponMapper userCouponMapper;
    @Autowired
    private IntegralGoodsUserMapper integralGoodsUserMapper;

    @Autowired
    private IntegralBizService integralBizService;

    @Autowired
    private IntegralUserMapper integralUserMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private PluginsManager pluginsManager;
    @Autowired
    private PrintMapper printMapper;

    @Autowired
    private OrderLogBizService orderLogBizService;

    /**
     * 下单
     * 1.商品下单
     *
     *  判断优惠券 /  商品
     *  优惠券
     *     1.积分兑换优惠券
     *          校验限兑量
     *          校验优惠券库存
     *
     *  商品
     *
     *  校验当前用户购买记录校验限购量  校验库存  （ 1.纯积分  记录积分  2.金额 积分混合  记录价格  记录所需积分）
     *
     *
     *
     * @param orderRequest
     * @param channel
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String takeIntegralGoodsOrder(OrderRequestDTO orderRequest, String channel, Long userId) throws ServiceException {
        if (lockComponent.tryLock(TAKE_ORDER_LOCK + userId, 20)) {
            //加上乐观锁，防止用户重复提交订单
            try {
                IntegralGoodsRequestDTO integralGoodsDTO = orderRequest.getIntegralGoodsDTO();
                //参数强校验 START
                if (integralGoodsDTO == null || orderRequest.getTotalPrice() == null || orderRequest.getTotalIntegral() == null) {
                    throw new AppServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
                }
                if (orderRequest.getTotalPrice() <= 0 && orderRequest.getTotalIntegral() <= 0) {
                    throw new AppServiceException(ExceptionDefinition.ORDER_PRICE_MUST_GT_ZERO);
                }
                if (orderRequest.getAddressId() == null) {
                    throw new AppServiceException(ExceptionDefinition.ORDER_ADDRESS_CANNOT_BE_NULL);
                }
                //积分商品校验

                    //某些产品已经下架
                    IntegralGoodsDO integralGoodsDO = integralGoodsMapper.selectById(integralGoodsDTO.getId());
                    if(IntegralGoodsStatusType.START.getCode() != integralGoodsDO.getStatus().intValue()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_GOODS_NOT_FOUND);
                    }
                    //限制购买数量
                    Integer userByCountSum = integralGoodsUserMapper.getUserByCountSum(userId, integralGoodsDO.getId())==null ? 0:integralGoodsUserMapper.getUserByCountSum(userId, integralGoodsDTO.getId());
                    if(userByCountSum.intValue() >= integralGoodsDO.getSkuLimit().intValue()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_GOODS_PURCHASE_UPPER);
                    }
                    SkuDO skuDO = skuMapper.selectById(integralGoodsDO.getSkuId());
                    if(skuDO.getStock() == null && skuDO.getStock().floatValue() <= 0 ){
                        throw new AppServiceException(ExceptionDefinition.ORDER_SKU_STOCK_NOT_ENOUGH_V2);
                    }
                    if(IntegralRuleType.SINGLE.getCode() == integralGoodsDO.getType().intValue()){
                        if(integralGoodsDO.getAmount() == null){
                            integralGoodsDO.setAmount(0);
                        }
                    }

                //用户会员等级
                Integer userLevel = SessionUtil.getUser().getLevel();
                OrderDO orderDO = new OrderDO();
                Long colonelLevelId = null;
                Long storeId = orderRequest.getStoreId();
                Long colonelStoreId = 0L;
                if (orderRequest.getColonelId() != null && orderRequest.getColonelId() > 0) {
                    orderDO.setColonelId(orderRequest.getColonelId());
                    ////需要处理团长的佣金和推荐团长人的佣金
                    //查找到团长可以提取佣金的商品，获取到团长的佣金比例
                    //TODO
                    /*ColonelDO colonelDO = colonelMapper.selectById(orderRequest.getColonelId());
                    colonelLevelId = colonelDO.getColonelLevel();*/
                } else {
                    orderDO.setColonelId(0L);
                }
                //强制匹配门店
                if (storeId == null || storeId.longValue() == 0l) {
                    //随机生成门店
                    List<StoreDO> status = storeMapper.selectList(new EntityWrapper<StoreDO>().eq("status", 1));
                    storeId = status.get(0).getId();
                }

                //商品价格
                int skuPrice = 0;
                int skuOriginalPrice = 0;
                //商品积分
                Integer integral=0;
                //稍后用于插入OrderSku
                Map<Long, IntegralGoodsDO> integralGoodsMap = new HashMap<>();
                List<SkuDTO> stockNotEnoughList = new ArrayList<>();
                List<SkuDTO> limitList = new ArrayList<>();
                List<SkuDTO> statusList = new ArrayList<>();
                    SkuDTO skuDTO = skuMapper.getSkuDTOById(integralGoodsDO.getSkuId());
                    //判断商品类型
                    integralGoodsMap.put(integralGoodsDTO.getId(), integralGoodsDO);
                    //当前为请求头中  商品 的  购价计算
                    int p;
                    p = (int) (integralGoodsDO.getAmount() * integralGoodsDTO.getNum());
                    skuPrice += p;
                    skuOriginalPrice += skuDTO.getOriginalPrice() * integralGoodsDTO.getNum();
                    integral=integralGoodsDO.getIntegral() * integralGoodsDTO.getNum();

                //价格校验
                if (skuPrice != orderRequest.getTotalPrice()) {
                    throw new AppServiceException(ExceptionDefinition.ORDER_PRICE_CHECK_FAILED);
                }
                //积分校验
                if(integral != orderRequest.getTotalIntegral()){
                    throw new AppServiceException(ExceptionDefinition.ORDER_INTEGRAL_CHECK_FAILED);
                }
                //运费计算
                List<OrderRequestSkuDTO> skuList=new ArrayList<>();
                OrderRequestSkuDTO requestSkuDTO=new OrderRequestSkuDTO();
                requestSkuDTO.setSkuId(skuDO.getId());
                requestSkuDTO.setPrice(integralGoodsDTO.getAmount());
                requestSkuDTO.setNum(integralGoodsDTO.getNum().floatValue());
                skuList.add(requestSkuDTO);
                orderRequest.setSkuList(skuList);
                Integer freightPrice = 0;
                //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //!!!!!!!!!!!!!!!!!!!!!自提商品不计算运费!!!!!!!!!!!!!!!
                freightPrice = freightBizService.getFreightMoney(orderRequest);

                //参数强校验 END
                //???是否校验actualPrice??强迫校验？
                Date now = new Date();
                String orderNo = GeneratorUtil.genOrderId(MACHINE_NO, ENV);
                //分销抵扣金额
                Integer deductionSum = orderRequest.getDeductionSum();
                orderDO.setDeductionPrice(deductionSum);
                //实付金额
                int actualPrice = skuPrice + freightPrice - ((deductionSum != null && deductionSum > 0) ? deductionSum : 0);


                orderDO.setSkuTotalPrice(skuPrice);
                orderDO.setSkuOriginalTotalPrice(skuOriginalPrice);
                orderDO.setChannel(channel);
                orderDO.setActualPrice(actualPrice);
                orderDO.setMono(orderRequest.getMono());
                orderDO.setFreightPrice(freightPrice);
                orderDO.setOrderNo(orderNo);
                orderDO.setUserId(userId);
                orderDO.setStatus(OrderStatusType.UNPAY.getCode());
                orderDO.setGmtUpdate(now);
                orderDO.setGmtCreate(now);
                 orderDO.setColonelId(orderRequest.getColonelId());
                //添加积分兑换
                orderDO.setIntergal(orderRequest.getTotalIntegral());
                if (orderRequest.getAddressId() != null) {
                    AddressDO addressDO = addressMapper.selectById(orderRequest.getAddressId());
                    if (!userId.equals(addressDO.getUserId())) {
                        throw new AppServiceException(ExceptionDefinition.ORDER_ADDRESS_NOT_BELONGS_TO_YOU);
                    }
                    orderDO.setConsignee(addressDO.getConsignee());
                    orderDO.setPhone(addressDO.getPhone());
                    orderDO.setProvince(addressDO.getProvince());
                    orderDO.setCity(addressDO.getCity());
                    orderDO.setCounty(addressDO.getCounty());
                    orderDO.setAddress(addressDO.getAddress());
                }
                orderMapper.insert(orderDO);
                //ordertype
                //添加订单流水
                insertOrderLog(orderDO);
                //
                    //此为积分商品
                    if(IntegralGoodsType.EXCHANGEGOOD.getCode() == integralGoodsDO.getGoodsType().intValue()){
                    OrderSkuDO orderSkuDO = new OrderSkuDO();
                    orderSkuDO.setBarCode(skuDTO.getBarCode());
                    orderSkuDO.setTitle(skuDTO.getTitle());
                    orderSkuDO.setUnit(skuDTO.getUnit());
                    orderSkuDO.setSpuTitle(skuDTO.getSpuTitle());
                    orderSkuDO.setImg(skuDTO.getImg() == null ? skuDTO.getSpuImg() : skuDTO.getImg());
                    orderSkuDO.setNum(integralGoodsDTO.getNum());
                    orderSkuDO.setOriginalPrice(skuDTO.getOriginalPrice());
                    orderSkuDO.setPrice(integralGoodsDO.getAmount());
                    orderSkuDO.setSkuId(skuDTO.getId());
                    orderSkuDO.setSpuId(skuDTO.getSpuId());
                    orderSkuDO.setOrderNo(orderDO.getOrderNo());
                    orderSkuDO.setOrderId(orderDO.getId());
                    orderSkuDO.setColonelId(orderRequest.getColonelId());
                    orderSkuDO.setGmtCreate(now);
                    orderSkuDO.setGmtUpdate(now);
                    orderSkuDO.setTotalSkuPrice(integralGoodsDTO.getNum()*integralGoodsDO.getAmount());
                    orderSkuDO.setIntegral(integralGoodsDTO.getNum()*integralGoodsDO.getIntegral());
                    orderSkuMapper.insert(orderSkuDO);
                    cacheComponent.del(CA_SPU_PREFIX + skuDTO.getSpuId());
                    //扣除库存
                    skuMapper.decSkuStock(integralGoodsDTO.getSkuId(), integralGoodsDTO.getNum().floatValue());
                    }

                IntegralUserDO currentUserMessage=new IntegralUserDO();
                Wrapper<IntegralUserDO> integralGoodsUserWrapper = new EntityWrapper<IntegralUserDO>();
                integralGoodsUserWrapper.eq("user_id",userId);
                List<IntegralUserDO> integralUserDOS = integralUserMapper.selectList(integralGoodsUserWrapper);
                if(integralUserDOS == null || integralUserDOS.size() < 1){
                    throw new AppServiceException(ExceptionDefinition.INTEGRAL_USERNOT_ENOUGH);
                }
                currentUserMessage=integralUserDOS.get(0);
                Integer totalIntegral = currentUserMessage.getTotalIntegral();
                //判断购买商品类型    纯积分  扣除积分    现金+积分  校验积分
                if(IntegralRuleType.SINGLE.getCode() == integralGoodsDO.getType().intValue() && actualPrice == 0){
                    orderCallback(orderDO);
                    //扣除积分
                    //计算积分扣除
                    if(totalIntegral < orderRequest.getTotalIntegral()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_USERNOT_ENOUGH);
                    }
                    Integer currentIntegral=totalIntegral - orderRequest.getTotalIntegral();
                    currentUserMessage.setTotalIntegral(currentIntegral);
                    currentUserMessage.setGmtUpdate(now);
                    SpuDO spuDO = spuMapper.selectById(integralGoodsDO.getSpuId());
                    String title="商品";
                    if(spuDO!=null){
                        title=spuDO.getTitle();
                    }
                    //添加积分商品兑换量
                    Float sales = integralGoodsDO.getSales();
                    Float num = integralGoodsDTO.getNum().floatValue();
                    integralGoodsDO.setSales(sales+num);
                    integralGoodsMapper.updateById(integralGoodsDO);
                    integralBizService.decIntegralDetail(orderRequest.getTotalIntegral(),orderRequest.getTotalPrice(),currentUserMessage,IntegralType.SPEND.getCode(),IntegralSonType.GOODS.getCode(),orderDO.getId(),title);
                }else{
                    if(integralUserDOS == null || integralUserDOS.size() < 1){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_USERNOT_ENOUGH);
                    }
                    if(totalIntegral < orderRequest.getTotalIntegral()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_USERNOT_ENOUGH);
                    }
                }
                //混合支付积分不足时提示
                insertUserGoodsLog(integralGoodsDTO.getId(), integralGoodsDTO.getNum().floatValue(), userId);
                //判断是否走纯余额支付

                return orderDO.getOrderNo();
            } catch (ServiceException e) {
                throw e;
            } catch (Exception e) {
                logger.error("[提交订单] 异常", e);
                throw new AppServiceException(ExceptionDefinition.ORDER_UNKNOWN_EXCEPTION);
            } finally {
                lockComponent.retree(TAKE_ORDER_LOCK + userId);
            }
        }
        throw new AppServiceException(ExceptionDefinition.ORDER_SYSTEM_BUSY);
    }

    /**
     * 积分商城优惠券下单
     * @param orderRequest
     * @param channel
     * @param userId
     * @return
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String takeIntegralCouponOrder(OrderRequestDTO orderRequest, String channel, Long userId) throws ServiceException {
        if (lockComponent.tryLock(TAKE_ORDER_LOCK + userId, 20)) {
            //加上乐观锁，防止用户重复提交订单
            try {
                //参数强校验 START
                IntegralGoodsRequestDTO integralGoodsDTO = orderRequest.getIntegralGoodsDTO();
                if (integralGoodsDTO == null || orderRequest.getTotalIntegral() == null) {
                    throw new AppServiceException(ExceptionDefinition.PARAM_CHECK_FAILED);
                }
                if (orderRequest.getTotalIntegral() <= 0) {
                    throw new AppServiceException(ExceptionDefinition.ORDER_PRICE_MUST_GT_ZERO);
                }
                //积分商品是否可以 兑换
                    //某些产品已经下架
                    IntegralGoodsDO integralGoodsDO = integralGoodsMapper.selectById(integralGoodsDTO.getId());
                    if(IntegralGoodsStatusType.START.getCode() != integralGoodsDO.getStatus().intValue()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_GOODS_NOT_FOUND);
                    }
                    //限制购买数量
                    Integer userByCountSum = integralGoodsUserMapper.getUserByCountSum(userId, integralGoodsDTO.getId()) ==null? 0:integralGoodsUserMapper.getUserByCountSum(userId, integralGoodsDTO.getId());
                    if(userByCountSum.intValue() >= integralGoodsDO.getSkuLimit().intValue()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_GOODS_PURCHASE_UPPER);
                    }
                    if(integralGoodsDTO.getNum() > integralGoodsDO.getSkuLimit().intValue()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_GOODS_PURCHASE_UPPER);
                    }
                    //库存不足  (当前方法只限制优惠券)
                    CouponDO couponDO = couponMapper.selectById(integralGoodsDO.getConponId());
                    if(integralGoodsDTO.getNum().intValue() > couponDO.getTotal()){
                        throw new AppServiceException(ExceptionDefinition.INTEGRAL_GOODS_NOT_ENOUGH);
                    }

                //用户会员等级
                Integer userLevel = SessionUtil.getUser().getLevel();
                OrderDO orderDO = new OrderDO();
                Long colonelLevelId = null;
                Long storeId = orderRequest.getStoreId();
                Long colonelStoreId = 0L;
                if (orderRequest.getColonelId() != null && orderRequest.getColonelId() > 0) {
                    orderDO.setColonelId(orderRequest.getColonelId());
                    ////需要处理团长的佣金和推荐团长人的佣金
                    //查找到团长可以提取佣金的商品，获取到团长的佣金比例
                    //TODO
                /*    ColonelDO colonelDO = colonelMapper.selectById(orderRequest.getColonelId());
                    colonelLevelId = colonelDO.getColonelLevel();
                */ } else {
                    orderDO.setColonelId(0L);
                }
                //强制匹配门店
                if (storeId == null || storeId.longValue() == 0l) {
                    //随机生成门店
                    List<StoreDO> status = storeMapper.selectList(new EntityWrapper<StoreDO>().eq("status", 1));
                    storeId = status.get(0).getId();
                }

                //商品价格
                int couponIntegral = 0;
//                int skuOriginalPrice = 0;
                //稍后用于插入OrderSku
                Map<Long, IntegralGoodsDO> integralGoodsMap = new HashMap<>();
                    //判断商品类型
                    integralGoodsMap.put(integralGoodsDTO.getId(), integralGoodsDO);
                    //计算总积分值
                    couponIntegral= couponIntegral+ (integralGoodsDTO.getNum()* integralGoodsDTO.getIntegral());

                // 订单积分 与 金额 校验
                if (couponIntegral != orderRequest.getTotalIntegral()) {
                    throw new AppServiceException(ExceptionDefinition.ORDER_PRICE_CHECK_FAILED);
                }
                //参数强校验 END
                //???是否校验actualPrice??强迫校验？
                Date now = new Date();

                String orderNo = GeneratorUtil.genOrderId(MACHINE_NO, ENV);
                //实付金额

                orderDO.setSkuTotalPrice(0);
                orderDO.setSkuOriginalTotalPrice(0);
                orderDO.setChannel(channel);
                orderDO.setActualPrice(0);
                orderDO.setMono(orderRequest.getMono());
                orderDO.setOrderNo(orderNo);
                orderDO.setUserId(userId);
                orderDO.setStatus(OrderStatusType.COMPLETE.getCode());
                orderDO.setGmtUpdate(now);
                orderDO.setGmtCreate(now);
                orderDO.setColonelId(orderRequest.getColonelId());
                //添加积分兑换
                orderDO.setIntergal(orderRequest.getTotalIntegral());
                orderDO.setFreightPrice(0);
                orderMapper.insert(orderDO);
                //ordertype
                orderDO.setBuyType(OrderBuyType.DISPATCH.getCode());
                //insertOrderType(orderDO,integralGoodsDO,now);
                //添加订单流水
                insertOrderLog(orderDO);
                //
                    //此为积分优惠券
                    if(IntegralGoodsType.EXCHANGECOUPON.getCode() == integralGoodsDO.getGoodsType().intValue()){
                        Long conponId = integralGoodsDO.getConponId();
                        OrderSkuDO orderSkuDO = new OrderSkuDO();
                        orderSkuDO.setBarCode(couponDO.getId()+"");
                        orderSkuDO.setTitle(couponDO.getTitle());
//                        orderSkuDO.setUnit("优惠券单位");
                        orderSkuDO.setSpuTitle(couponDO.getTitle());
//                        orderSkuDO.setImg("优惠券图片");
                        orderSkuDO.setNum(integralGoodsDTO.getNum());
                        orderSkuDO.setOriginalPrice(0);
                        orderSkuDO.setPrice(0);
                        orderSkuDO.setSkuId(couponDO.getId());
                        orderSkuDO.setSpuId(couponDO.getId());
                        orderSkuDO.setOrderNo(orderDO.getOrderNo());
                        orderSkuDO.setOrderId(orderDO.getId());
                        orderSkuDO.setColonelId(orderRequest.getColonelId());
                        orderSkuDO.setImg(couponDO.getTitle());
                        orderSkuDO.setIntegral(integralGoodsDTO.getIntegral());
                        orderSkuDO.setGmtCreate(now);
                        orderSkuDO.setGmtUpdate(now);
                        orderSkuMapper.insert(orderSkuDO);
                        //扣除  优惠券量
                        Float current = couponDO.getTotal().floatValue() - integralGoodsDTO.getNum().floatValue();
                        couponDO.setTotal(current.intValue());
                        couponMapper.updateById(couponDO);
                        //将优惠券加到当前用户下
                        UserCouponDO param=new UserCouponDO();
                        //根据优惠券类型判断   有效期
                        param.setCouponId(couponDO.getId());
                        param.setUserId(userId);
                        param.setGmtCreate(now);
                        param.setGmtUpdate(now);
                        if(couponDO.getGmtStart() == null && couponDO.getGmtEnd() == null && couponDO.getDays() != 0){
                            couponDO.setGmtStart(now);
                            couponDO.setGmtEnd(DateUtils.getBeforeSomeDaysDate(now,couponDO.getDays()));
                        }
                        param.setGmtStart(couponDO.getGmtStart());
                        param.setGmtEnd(couponDO.getGmtEnd());
                        userCouponMapper.insert(param);
                    }
                //扣除积分
                IntegralUserDO currentUserMessage=new IntegralUserDO();
                Wrapper<IntegralUserDO> integralGoodsUserWrapper = new EntityWrapper<IntegralUserDO>();
                integralGoodsUserWrapper.eq("user_id",userId);
                List<IntegralUserDO> integralUserDOS = integralUserMapper.selectList(integralGoodsUserWrapper);
                if(integralUserDOS == null || integralUserDOS.size() < 1){
                    throw new AppServiceException(ExceptionDefinition.INTEGRAL_USERNOT_ENOUGH);
                }
                currentUserMessage=integralUserDOS.get(0);
                //计算积分扣除
                Integer totalIntegral = currentUserMessage.getTotalIntegral();
                if(totalIntegral < orderRequest.getTotalIntegral()){
                    throw new AppServiceException(ExceptionDefinition.INTEGRAL_USERNOT_ENOUGH);
                }
                Integer currentIntegral=totalIntegral - orderRequest.getTotalIntegral();
                currentUserMessage.setTotalIntegral(currentIntegral);
                currentUserMessage.setGmtUpdate(now);
                SpuDO spuDO = spuMapper.selectById(integralGoodsDO.getSpuId());
                String title="商品兑换";
                if(spuDO!=null){
                     title=spuDO.getTitle();
                    integralBizService.decIntegralDetail(couponIntegral,orderRequest.getTotalPrice(),currentUserMessage,IntegralType.SPEND.getCode(),IntegralSonType.GOODS.getCode(),orderDO.getId(),title);
                }
                insertUserGoodsLog(integralGoodsDTO.getId(), integralGoodsDTO.getNum().floatValue(), userId);
                //判断是否走纯余额支付
                return orderDO.getOrderNo();
            } catch (ServiceException e) {
                throw e;
            } catch (Exception e) {
                logger.error("[提交订单] 异常", e);
                throw new AppServiceException(ExceptionDefinition.ORDER_UNKNOWN_EXCEPTION);
            } finally {
                lockComponent.retree(TAKE_ORDER_LOCK + userId);
            }
        }
        throw new AppServiceException(ExceptionDefinition.ORDER_SYSTEM_BUSY);
    }


    /**
     * 添加订单记录
     */
    public void insertOrderLog(OrderDO orderDO){
        OrderLogDO orderLogDO = new OrderLogDO();
        orderLogDO.setOrderId(orderDO.getId());
        orderLogDO.setOrderNo(orderDO.getOrderNo());
        orderLogDO.setLastStatus(null);
        orderLogDO.setCurrentStatus(orderDO.getStatus());
        String detail = JSON.toJSONString(orderDO);
        orderLogDO.setDetail(detail);
        orderLogBizService.addOrderLog(orderLogDO);
    }

    /**
     * 纯积分订单 购买
     * @param order
     */
    public void integralOrder(OrderDO order) throws ServiceException {
        orderCallback(order);
         //打印订单数据
        printOrder(order);
        //添加订单流水
        OrderLogDO orderLogDO = new OrderLogDO();
        orderLogDO.setOrderId(order.getId());
        orderLogDO.setOrderNo(order.getOrderNo());
        orderLogDO.setLastStatus(order.getStatus());
        orderLogDO.setCurrentStatus(OrderStatusType.WAIT_STOCK.getCode());
        String detail = JSON.toJSONString(order);
        orderLogDO.setDetail(detail);
        orderLogBizService.addOrderLog(orderLogDO);
    }

    /**
     * 记录购买记录
     * @param integralGoodsId
     * @param num
     * @param userId
     */
    public void insertUserGoodsLog(Long integralGoodsId,Float num,Long userId){
        IntegralGoodsUserDO insert=new IntegralGoodsUserDO();
        insert.setIntegralGoodsId(integralGoodsId);
        insert.setNum(num);
        insert.setUserId(userId);
        insert.setGmtUpdate(new Date());
        insert.setGmtCreate(new Date());
        integralGoodsUserMapper.insert(insert);
    }

    Boolean printOrder(OrderDO order){
        PrintDO printDO = new PrintDO();
        try {
            logger.info("======================支付成功回调订单打印==================================");
            EntityWrapper<PrintDO> wrapper = new EntityWrapper<PrintDO>();
            List<PrintDO> list = printMapper.selectList(wrapper);
            if (list == null || list.size() == 0) {
                return false;
            }
            printDO = list.get(0);
            if (printDO == null) {
                return false;
            }
            Integer autoPrint = printDO.getIsAuto() == null ? 0 : printDO.getIsAuto();
            logger.info("<<<<<<<<<<<printDO.getIsAuto()  -->  " + printDO.getIsAuto());
            //判断是否自动打印
            if (PrintAutoType.YES.getCode() != autoPrint.intValue()) {
                logger.info("======================" + printDO.getStoreId() + " ==========不支持订单自动打印=======================");
                return false;
            }
            logger.info("======================" + printDO.getStoreId() + " ==========订单自动打印=======================");
            OrderDTO orderDto = orderBizService.getOrderDetail(order.getId(), null, null);
            HttpClientUtil httpClientUtil = new HttpClientUtil();
            String url = SunmiConfig.RESURL + "/v1/printer/pushContent";
            logger.info("callbackprintOrder====url====================printDO==>>>>" + printDO.getAppId() + "====>>>>>>=================================" + url);
            Map<String, Object> map = new HashMap<String, Object>();
            SignUtils su = new SignUtils();
            String timestamp = su.getTimestamp();
            map.put("app_id", printDO.getAppId());
            map.put("msn", printDO.getPrintSn());
            map.put("timestamp", timestamp);
            double money = order.getActualPrice() * 0.01;
            BigDecimal b = new BigDecimal(money);
            money = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //私有参数
            map.put("pushId", order.getOrderNo() + RomCodeUtil.getMemberCardCode());
            logger.info("callbackprintOrder=============pushId=================" + order.getOrderNo() + RomCodeUtil.getMemberCardCode() + "====================================");
            map.put("voiceCnt", 1);
            map.put("voice", "打印新订单啦!实收金额" + (money) + "元");
            map.put("orderCnt", 1);
            map.put("orderType", 1);
            String storeName = "睢宁菜系直营店";
            String info = EscPosUtil.getOrderString(orderDto, storeName);
            map.put("orderData", bytesToHexString(toUtf8(info).getBytes()));
            String sign = su.createSign(map, printDO.getAppKey());
            map.put("sign", sign);
            String kk = httpClientUtil.doPost(url, map);
        } catch (Exception e) {
            logger.info("callbackprintOrder=============printdo========================================is null" + e.getMessage());

            e.getMessage();
        }
        //PrintUtil.printSheet(order);
        return true;
    }

    public static final String bytesToHexString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    public static String toUtf8(String str) throws UnsupportedEncodingException {
        return new String(str.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
    }


    /**
     *
     * @param orderDO
     */
    void orderCallback(OrderDO orderDO) throws ServiceException {
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>支付成功的订单  订单后续处理>>>>>>>>>>>>>>>>>>>>>>>>");
        logger.info(">>>>>>>>>>>>>>>>>>>orderCallback  orderNo->(" + orderDO.getOrderNo() + ")>>>>>>>>>>>>>>>>>>>>>");
        OrderDO updateOrderDO = new OrderDO();
        updateOrderDO.setPayChannel("INTEGRAL");
        updateOrderDO.setGmtPay(new Date());
        updateOrderDO.setGmtUpdate(orderDO.getGmtPay());
        updateOrderDO.setStatus(OrderStatusType.WAIT_STOCK.getCode());
        orderBizService.changeOrderStatus(orderDO.getOrderNo(), OrderStatusType.UNPAY.getCode(), updateOrderDO);
        List<OrderSkuDO> orderSkuDOList = orderSkuMapper.selectList(
                new EntityWrapper<OrderSkuDO>()
                        .eq("order_no", orderDO.getOrderNo()));
        orderSkuDOList.forEach(item -> {
            //增加销量
            spuMapper.incSales(item.getSpuId(), item.getNum());

        });

        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(orderDO, orderDTO);
        orderDTO.setPayChannel(updateOrderDO.getPayChannel());
        orderDTO.setSkuList(orderSkuDOList);

        List<IPluginPaySuccess> plugins = pluginsManager.getPlugins(IPluginPaySuccess.class);
        if (!CollectionUtils.isEmpty(plugins)) {
            String formId = userBizService.getValidFormIdByUserId(orderDTO.getUserId()).getFormId();
            for (IPluginPaySuccess paySuccess : plugins) {
                orderDTO = paySuccess.invoke(orderDTO, formId);
            }
        }
        //通知管理员发货
        OrderDTO finalOrderDTO = orderDTO;
        GlobalExecutor.execute(() -> {
            adminNotifyBizService.newOrderAndPrint(finalOrderDTO);
        });
    }


    public static void main(String[] args) {
        //优惠券下单实例
        IntegralGoodsRequestDTO goodsdto=new IntegralGoodsRequestDTO();
        goodsdto.setId(153L);
        goodsdto.setSkuId(3541L);
        goodsdto.setNum(2);
        goodsdto.setIntegral(1);
        goodsdto.setAmount(1);//单价
        OrderRequestDTO dto=new OrderRequestDTO();
        dto.setTotalIntegral(2);
        dto.setTotalPrice(2);
        dto.setDeductionSum(1);
        dto.setAddressId(1387l);
        dto.setStoreId(16l);
        dto.setColonelId(16l);
        dto.setFreightPrice(1);
        dto.setIntegralGoodsDTO(goodsdto);
        System.out.println(JSON.toJSON(dto));
    }
}
